package com.meltingslime.asciifight.server.network;

import org.apache.log4j.Logger;

import java.io.*;
import java.net.Socket;

/**
 * @author Exit93
 * @version 1.0
 */
public class Client extends Thread implements Closeable {

    private Socket client;
    private DataInputStream inStream;
    private DataOutputStream outStream;

    private boolean connected = false;

    private Logger log = Logger.getLogger("asciifight.server.client");

    public Client(Socket client){
        this.client = client;
        try {
            inStream = new DataInputStream(client.getInputStream());
            outStream = new DataOutputStream(client.getOutputStream());
        } catch (IOException e) {
            log.error("Error while getting client stream.", e);
            close();
            return;
        }
        connected = true;

        log.info("Accepted connection from " + getAddress());

        start(); // Starts listening
    }

    public boolean isConnected(){
        return connected;
    }

    public String getAddress(){
        return client.getRemoteSocketAddress().toString();
    }

    public void run(){
        listen();
    }

    private void listen(){
        while (connected){
            try {
                byte id = inStream.readByte();

                int length = inStream.readInt();

                byte[] data = new byte[length];
                inStream.readFully(data, 0, data.length);

                processPacket(id, data);

            } catch (IOException e) {
                if (!connected){ // Connection has been dropped
                    close(); // Make sure to close anything
                    return;
                }

            }
        }
    }

    public void processPacket(byte id, byte[] data) {
        log.debug("Received packet id " + id + " from: " + getAddress());
        //TODO React
    }

    @Override
    public void close() {
        connected = false;
        try {
            inStream.close();
            outStream.close();
            client.close();
        } catch (IOException ignore) {}
        finally {
            log.info("Closing connection with " + getAddress());
        }
    }
}
